<?php
declare(strict_types=1);
namespace App\Middleware;
use GuzzleHttp\Client;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Router\Dispatched;
use Hyperf\Utils\ApplicationContext;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
class AuthMiddleware implements MiddlewareInterface
{
    /** * @var ContainerInterface */
    protected $container;
    /** * @var RequestInterface */
    protected $request;
    /** * @var HttpResponse */
    protected $response;
    public function __construct(ContainerInterface $container, RequestInterface $request, HttpResponse $response)
    {
        $this->container = $container;
        $this->request = $request;
        $this->response = $response;
    }
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $result = $this->checkAuth($request);

        if ($result == '401') {
            // 鉴权失败，返回未授权错误
            return $this->response->json([
                'code' => 401,
                'message' => '没有对应的权限',
            ]);
        }
        if ($result == '402') {
            // 鉴权失败，返回未授权错误
            return $this->response->json([
                'code' => 402,
                'message' => 'token 已过期',
            ]);
        }
        return $handler->handle($request);
    }
    private function checkAuth(ServerRequestInterface $request)
    {
        // 鉴权通过返回 true，鉴权失败返回 false
        try {
            $container = ApplicationContext::getContainer();
            $this->redisService = $container->get(\Hyperf\Redis\Redis::class);

            $access_token =  $request->getHeader('Mema-Token')[0];

            if(empty($access_token)){
                return 402;
            }
            $redisKey = 'web_userInfo:'.$access_token;
//            var_dump($redisKey);
            //查找redis上是否有对应的token
            $userInfo = $this->redisService->get($redisKey);
            if(empty($userInfo)){
                return 402;
            }
            //判断是否过期
            $userInfo = json_decode($userInfo,true);
            if(time() > $userInfo['expire_in']){
                $this->redisService->del($redisKey);
                return 402;
            }
            //判断是否为管理员
            $permissions = $userInfo['permissions'];
            if(empty($permissions)){
                return 401;
            }

            $action = $this->request->getAttribute(Dispatched::class)->handler->callback;
            //获取请求的
            list($LongController, $method) = explode('@', $action);
            list($appDir,$controllerDir,$module,$controller) =  explode('\\', $LongController);
            $controller = lcfirst(str_replace('Controller','',$controller));
            $ruleUrl = $module.':'.$controller.':'.$method;

            //判断请求的url中是否有对应的权限
            if(!in_array($ruleUrl,$permissions)){
                return 401;
            }
            return 200;

        }catch (\Exception $e){
            var_dump($e->getMessage());
            return 402;
        }


    }

}